<?php


namespace App\Http\Controllers\User;


use App\Http\Common\BaseController;
use App\Http\Validator\LoginValidator;
use App\Http\Validator\UserValidator;
use App\Models\LoginBackground;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class LoginController extends BaseController
{
    /**
     * 获取登录背景
     * @param $start_time
     * @param $end_time
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function currentLoginBackground($startTime, $endTime, Request $request){
        $backgroundId = $request->get('backgroundId');

        //防止登录图片重复
        if ($backgroundId == null){
            $currentBg = LoginBackground::where([
                ['start_time', $startTime],
                ['end_time', $endTime]
            ])
                ->select(['id', 'author', 'url', 'region', 'source_address'])
                ->get()
                ->toArray();
        }else{
            $currentBg = LoginBackground::where([
                ['start_time', $startTime],
                ['end_time', $endTime],
                ['id', '<>', $backgroundId]
            ])
                ->select(['id', 'author', 'url', 'region', 'source_address'])
                ->get()
                ->toArray();
        }

        $rand = mt_rand(0, count($currentBg) - 1);

        return $this->returnJson(BaseController::SUCCESS, '', $currentBg[$rand]);
    }

    /**
     * 用户名登录
     * @param Request $request
     * @param LoginValidator $loginValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function usernameLogin(Request $request, LoginValidator $loginValidator){
        $params = $request->only(['username', 'password']);

        //判断输入格式
        if (!$loginValidator->setScene('usernameLogin')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $loginValidator->getError());
        }

        //判断用户是否存在
        $userInfo = User::where([
            'username'  =>  $params['username'],
            'password'  =>  md5($params['password'])
        ])->first();
        if (!$userInfo) return $this->returnJson(BaseController::DATA_NOTFOUND, '用户不存在');

        //登录成功进行操作, 获取token
        if (!$token = $this->loginSuccess($userInfo)) return $this->returnJson(BaseController::ERROR, '系统错误, 请重新尝试');

        return $this->returnJson(BaseController::SUCCESS, "用户名登录成功", [
            'token'     =>  $token,
            'is_first'  =>  $userInfo['is_first']
        ]);
    }

    /**
     * 手机号码登录
     * @param Request $request
     * @param LoginValidator $loginValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function phoneLogin(Request $request, LoginValidator $loginValidator){
        $params = $request->only(['phone', 'code']);

        //验证手机号和验证码
        if (!$loginValidator->setScene('check')->check($params)) {
            return $this->returnJson(BaseController::FIELD_ERROR, $loginValidator->getError());
        }

        //获取redis中的验证码
        if (!$smsCode = Redis::get($params['phone'])) {
            return $this->returnJson(BaseController::ERROR, '请输入正确的手机号码');
        }

        //验证码不正确
        if ($smsCode != $params['code']){
            return $this->returnJson(BaseController::ERROR, '请输入正确的验证码');
        }

        Redis::del($params['phone']);

        //使用手机号码获取用户信息
        $userInfo = User::where('phone', $params['phone'])->first();
        if (!$userInfo) return $this->returnJson(BaseController::DATA_NOTFOUND, '用户不存在');

        //登录成功进行操作, 获取token
        if (!$token = $this->loginSuccess($userInfo)) return $this->returnJson(BaseController::ERROR, '系统错误, 请重新尝试');

        return $this->returnJson(BaseController::SUCCESS, '登录成功', [
            'token'     =>  $token,
            'is_first'  =>  $userInfo['is_first']
        ]);
    }

    /**
     * 手机号登录发送验证码
     * @param Request $request
     * @param LoginValidator $loginValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \AlibabaCloud\Client\Exception\ClientException
     */
    public function phoneLoginSendVerifyCode(Request $request, LoginValidator $loginValidator){
        $params = $request->only(['phone']);

        //判断输入格式
        if (!$loginValidator->setScene('sms')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $loginValidator->getError());
        }

        //生成验证码
        $rand = mt_rand(111111, 999999);

        //判断用户是否存在
        if (!User::where('phone', $params['phone'])->first()) return $this->returnJson(BaseController::DATA_NOTFOUND, '当前用户不存在');

        //发送短信
        if (!is_null($smsError = $this->send($params['phone'], $rand))) {
            return $this->returnJson(BaseController::ERROR, '短信发送失败', $smsError);
        }

        //存储短信验证码
        Redis::setex($params['phone'], 300, $rand);

        return $this->returnJson(BaseController::SUCCESS, '验证码发送成功');
    }

    /**
     * 用户首次登录发送验证码
     * @param Request $request
     * @param LoginValidator $loginValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     * @throws \AlibabaCloud\Client\Exception\ClientException
     */
    public function firstLoginSendVerifyCode(Request $request, LoginValidator $loginValidator){
        $params = $request->only(['phone']);

        //判断输入格式
        if (!$loginValidator->setScene('sms')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $loginValidator->getError());
        }

        if (User::where('phone', $params['phone'])->first()) {
            return $this->returnJson(BaseController::ERROR, '手机号码已经被绑定');
        }

        //生成验证码
        $rand = mt_rand(111111, 999999);

        //发送短信
        if (!is_null($smsError = $this->send($params['phone'], $rand))) {
            return $this->returnJson(BaseController::ERROR, '短信发送失败', $smsError);
        }

        //存储短信验证码
        Redis::setex($params['phone'], 300, $rand);

        return $this->returnJson(BaseController::SUCCESS, '验证码发送成功');
    }

    /**
     * 登录成功操作
     * @param $userInfo
     * @return bool|string
     */
    private function loginSuccess($userInfo){
        if (Redis::get($userInfo['login_token'])){
            Redis::del($userInfo['login_token']);
        }

        if (Redis::get($userInfo['email_token'])){
            Redis::del($userInfo['email_token']);
        }

        //修改登录日期
        $update = User::where('id', $userInfo['id'])->update(['login_date' => time()]);
        if (!$update) return false;

        //生成token
        $token = $this->tokenPrefix . $this->makeToken($userInfo['id']);

        //用户信息
        $info = [
            'id'        =>  $userInfo['id'],
            'username'  =>  $userInfo['username'],
            'phone'     =>  $userInfo['phone'],
            'is_first'  =>  $userInfo['is_first'],
        ];

        //存储用户信息
        Redis::setex($token, 60 * 60 * 24, json_encode($info));

        User::where('id', $userInfo['id'])->update(['login_token' => $token]);

        return $token;
    }

    /**
     * 修改密码
     * @param Request $request
     * @param UserValidator $userValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function updatePass(Request $request, UserValidator $userValidator){
        $params = [
            'username'  =>  $request->input('username'),
            'password'  =>  $request->input('password'),
            'confirmPassword'   =>  $request->input('confirmPassword')
        ];

        //判断参数格式
        if (!$userValidator->setScene('updatePass')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $userValidator->getError());
        }

        //判断密码是否相同
        if ($params['password'] != $params['confirmPassword']) return $this->returnJson(BaseController::FIELD_ERROR, '密码和确认密码不相同');

        if (!$userData = User::find($request->userId)){
            return $this->returnJson(BaseController::ERROR, '密码修改失败');
        }

        //0：不用修改 1：修改密码和手机号码 2：修改密码
        if ($userData['is_first'] == 2){
            //修改密码
            User::where('id', $request->userId)->update([
                'password'  => md5($params['password']),
                'is_first'  => 0
            ]);
        }else{
            //修改密码
            User::where('id', $request->userId)->update(['password' => md5($params['password'])]);
        }

        return $this->returnJson(BaseController::SUCCESS, '密码修改成功');
    }

    /**
     * 修改手机号码
     * @param Request $request
     * @param UserValidator $userValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function updatePhone(Request $request, UserValidator $userValidator){
        $params = [
            'phone'     => $request->input('phone'),
            'code'      => $request->input('code')
        ];

        //判断参数格式
        if (!$userValidator->setScene('updatePhone')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $userValidator->getError());
        }

        //获取redis中的验证码
        if (!$smsCode = Redis::get($params['phone'])) {
            return $this->returnJson(BaseController::ERROR, '请输入正确的手机号码');
        }

        //验证码不正确
        if ($smsCode != $params['code']){
            return $this->returnJson(BaseController::ERROR, '请输入正确的验证码');
        }

        $userData = User::find($request->userId);
        if (!$userData) return $this->returnJson(BaseController::ERROR, '手机号码修改失败');;

        User::where('id', $request->userId)->update([
            'phone'     => $params['phone'],
            'is_first'  => 0
        ]);

        Redis::del($params['phone']);

        return $this->returnJson(BaseController::SUCCESS, '手机号码修改成功');
    }

    /**
     * 退出登录
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function loginOut(Request $request){
        //获取token
        $token = $request->header("Authorization");

        //删除用户
        Redis::del($token);

        return $this->returnJson(BaseController::SUCCESS, '退出登录成功');
    }

    /**
     * 刷新用户登录时间
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function refreshUserTime(Request $request){
        //获取token
        $token = $request->header("Authorization");

        //获取用户信息
        $userInfo = Redis::get($token);

        //修改用户登录时间
        Redis::setex($token, 60 * 60 * 24, $userInfo);

        return $this->returnJson(BaseController::SUCCESS, '刷新成功');
    }

}
